package org.hepeng.commons.util;

import net.openhft.compiler.CompilerUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.hepeng.commons.exception.ApplicationRuntimeException;
import org.springframework.util.Assert;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author he peng
 */
public class ClassUtils {


    public static Class getSingleGenericSuperclass(Class subClass) {
        Assert.notNull(subClass , "subClass must not be null");
        ParameterizedType parameterizedType = (ParameterizedType) subClass.getGenericSuperclass();
        Type[] types = parameterizedType.getActualTypeArguments();
        return ArrayUtils.isNotEmpty(types) ? (Class) types[0] : null;
    }

    public static List<Class> getMultipleGenericSuperclass(Class subClass) {
        Assert.notNull(subClass , "subClass must not be null");
        ParameterizedType parameterizedType = (ParameterizedType) subClass.getGenericSuperclass();
        Type[] types = parameterizedType.getActualTypeArguments();
        List<Class> classes = new ArrayList<>();
        if (ArrayUtils.isNotEmpty(types)) {
            for (Type type : types) {
                classes.add((Class) type);
            }
        }
        return classes;
    }

    @Deprecated
    public static Class compileFromJavaCode(String qualifiedClassName , String javaCode) {
        Assert.hasLength(qualifiedClassName , "qualifiedClassName must not be blank");
        Assert.hasLength(javaCode , "javaCode must not be blank");
        try {
            ClassLoader classLoader = ClassLoader.getSystemClassLoader();
            if (Objects.isNull(classLoader)) {
                classLoader = Thread.currentThread().getContextClassLoader();
            }
            return compileFromJavaCode(classLoader , qualifiedClassName , javaCode);
        } catch (Throwable t) {
            throw new ApplicationRuntimeException("compile java code error : " + t.getMessage() , t);
        }
    }

    @Deprecated
    public static Class compileFromJavaCode(ClassLoader classLoader , String qualifiedClassName , String javaCode) {
        Assert.notNull(classLoader , "classLoader must not be null");
        Assert.hasLength(qualifiedClassName , "qualifiedClassName must not be blank");
        Assert.hasLength(javaCode , "javaCode must not be blank");
        try {
            return CompilerUtils.CACHED_COMPILER.loadFromJava(classLoader , qualifiedClassName, javaCode);
        } catch (Throwable t) {
            throw new ApplicationRuntimeException("compile java code error : " + t.getMessage() , t);
        }
    }
}
